package cn.iocoder.an.module.mold.service.upkeeptobe;


import cn.iocoder.an.module.mold.controller.admin.upkeeptask2item.vo.UpkeepTask2itemSaveReqVO;
import cn.iocoder.an.module.mold.dal.dataobject.account.AccountDO;
import cn.iocoder.an.module.mold.dal.dataobject.upkeepcategory.UpkeepCategoryDO;
import cn.iocoder.an.module.mold.dal.dataobject.upkeepstatics.UpkeepStaticsDO;
import cn.iocoder.an.module.mold.dal.dataobject.upkeeptask.UpkeepTaskDO;
import cn.iocoder.an.module.mold.dal.dataobject.upkeeptask2item.UpkeepTask2itemDO;
import cn.iocoder.an.module.mold.dal.mysql.account.AccountMapper;
import cn.iocoder.an.module.mold.dal.mysql.upkeepcategory.UpkeepCategoryMapper;
import cn.iocoder.an.module.mold.dal.mysql.upkeepstatics.UpkeepStaticsMapper;
import cn.iocoder.an.module.mold.dal.mysql.upkeeptask.UpkeepTaskMapper;
import cn.iocoder.an.module.mold.dal.mysql.upkeeptask2item.UpkeepTask2itemMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;

import cn.iocoder.an.module.mold.controller.admin.upkeeptobe.vo.*;
import cn.iocoder.an.module.mold.dal.dataobject.upkeeptobe.UpkeepTobeDO;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.pojo.PageParam;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import cn.iocoder.an.module.mold.dal.mysql.upkeeptobe.UpkeepTobeMapper;

import static cn.iocoder.an.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.an.module.mold.enums.ErrorCodeConstants.*;

/**
 * 待保养模具 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class UpkeepTobeServiceImpl implements UpkeepTobeService {
    @Resource
    private UpkeepTobeMapper upkeepTobeMapper;

    @Resource
    private AccountMapper accountMapper;

    @Resource
    private UpkeepTaskMapper upkeepTaskMapper;


    @Resource
    private UpkeepTask2itemMapper upkeepTask2itemMapper;

    @Resource
    private UpkeepCategoryMapper upkeepCategoryMapper;

    @Resource
    private UpkeepStaticsMapper upkeepStaticsMapper;


    @Override
    public Long createUpkeepTobe(UpkeepTobeSaveReqVO createReqVO) {
        UpkeepTobeDO upkeepTobe = BeanUtils.toBean(createReqVO, UpkeepTobeDO.class);
        if (existsByAccountId(createReqVO.getAccountId())) {
            throw exception(UPKEEP_TOBE_MOLD_EXISTS);
        }

        //建议直接查询模具状态，然后
        AccountDO accountDO = accountMapper.selectById(upkeepTobe.getAccountId());
        UpkeepCategoryDO category = upkeepCategoryMapper.selectById(upkeepTobe.getUpkeepId());

        upkeepTobe.setDrawingNoId(accountDO.getDrawingNoId());
        //设置上次保养时间LocalDateTime
        upkeepTobe.setLastUpkeepTime(accountDO.getLastUpkeepTime());
        upkeepTobe.setNextUpkeepTime(accountDO.getNextUpkeepTime());

        //状态管理  待派工 需要与字段对应
        upkeepTobe.setStatus(1);
        upkeepTobe.setRemindF(0L);
        // 插入
        upkeepTobeMapper.insert(upkeepTobe);
        // 返回
        return upkeepTobe.getId();
    }

    @Override
    public void updateUpkeepTobe(UpkeepTobeSaveReqVO updateReqVO) {
        // 校验存在
        validateUpkeepTobeExists(updateReqVO.getId());
        // 更新
        UpkeepTobeDO updateObj = BeanUtils.toBean(updateReqVO, UpkeepTobeDO.class);
        upkeepTobeMapper.updateById(updateObj);
    }

    @Override
    public void deleteUpkeepTobe(Long id) {
        // 校验存在
        validateUpkeepTobeExists(id);
        // 删除
        upkeepTobeMapper.forceDeleteById(id);
    }

    @Override
    public void deleteUpkeepTobeListByIds(List<Long> ids) {
        // 删除
        upkeepTobeMapper.deleteByIds(ids);
    }


    private void validateUpkeepTobeExists(Long id) {
        if (upkeepTobeMapper.selectById(id) == null) {
            throw exception(UPKEEP_TOBE_NOT_EXISTS);
        }
    }

    @Override
    public UpkeepTobeDO getUpkeepTobe(Long id) {
        return upkeepTobeMapper.selectById(id);
    }

    @Override
    public PageResult<UpkeepTobeDO> getUpkeepTobePage(UpkeepTobePageReqVO pageReqVO) {
        return upkeepTobeMapper.selectPage(pageReqVO);
    }


    public Boolean existsByAccountId(Long accountId) {
        // 使用 QueryWrapper 进行查询
        QueryWrapper<UpkeepTobeDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_id", accountId);
        return upkeepTobeMapper.selectCount(queryWrapper) > 0;
    }


    @Override
    public Boolean dispatch(UpkeepTobeDispatchVO dispatch) {
        //待保养任务Id
        long upkeepTobeId = dispatch.getId();
        Long assigneerId = dispatch.getAssigneerId();

        UpkeepTobeDO upkeepTobe = upkeepTobeMapper.selectById(upkeepTobeId);
        AccountDO accountDO = accountMapper.selectById(upkeepTobe.getAccountId());

        UpkeepTaskDO upkeepTask = new UpkeepTaskDO();
        upkeepTask.setCode(UUID.randomUUID().toString());
        upkeepTask.setDrawingNoId(upkeepTobe.getDrawingNoId());
        upkeepTask.setAccountId(upkeepTobe.getAccountId());
        upkeepTask.setUpkeepId(upkeepTobe.getUpkeepId());
        upkeepTask.setAssigneerId(assigneerId);
        upkeepTask.setNextUpkeepTime(accountDO.getNextUpkeepTime());
        upkeepTask.setTaskCreateTime(LocalDateTime.now());
        upkeepTask.setStatus(2);
        //创建task
        upkeepTaskMapper.insert(upkeepTask);

        //更新
        upkeepTobe.setTaskId(upkeepTask.getId());
        upkeepTobe.setStatus(2);
        upkeepTobeMapper.updateById(upkeepTobe);
        return true;
    }


    public Boolean cancelDispatch(Long id) {
        UpkeepTobeDO upkeepTobe = upkeepTobeMapper.selectById(id);
        if (upkeepTobe.getStatus() > 2) {
            throw exception(UPKEEP_TASK_ALREADY_RECEIVED);
        }
        //判断upkeepTobe

        //删除任务
        upkeepTaskMapper.deleteById(upkeepTobe.getTaskId());

        //修改待保养任务状态
        upkeepTobe.setTaskId(null);
        upkeepTobe.setStatus(1);
        //更新
        upkeepTobeMapper.updateById(upkeepTobe);
        return true;
    }

    public Boolean audit(UpkeepTobeAuditVO audit) {
        int upkeepStatus   =  6 ;
        UpkeepTaskDO task = upkeepTaskMapper.selectById(audit.getId());
        UpkeepTobeDO tobe = upkeepTobeMapper.selectOne(new LambdaQueryWrapper<UpkeepTobeDO>().eq(UpkeepTobeDO::getTaskId, task.getId()));
        task.setActualStartTime(audit.getActualStartTime());
        task.setActualEndTime(audit.getActualEndTime());
        task.setActualExecutionDuration(audit.getActualExecutionDuration());
        task.setAuditDescription(audit.getAuditDescription());
        //这里需要先删除task2item
        upkeepTask2itemMapper.delete(new LambdaQueryWrapper<UpkeepTask2itemDO>()
                .eq(UpkeepTask2itemDO::getTaskId, task.getId()));
        //循环插入items
        if (audit.getUpkeepItems().size() > 0) {
            for (UpkeepTask2itemSaveReqVO item : audit.getUpkeepItems()) {
                upkeepTask2itemMapper.insert(BeanUtils.toBean(item, UpkeepTask2itemDO.class));
            }
        }
        task.setStatus(upkeepStatus);
        upkeepTaskMapper.updateById(task);
        tobe.setStatus(upkeepStatus);
        upkeepTobeMapper.updateById(tobe);
        //todo :审核完成后  需要同步更新模具的保养状态
        AccountDO accountDO = accountMapper.selectById(tobe.getAccountId());
        UpkeepCategoryDO upkeepCategoryDO = upkeepCategoryMapper.selectById(accountDO.getUpkeepId());
        //上次保养日期
        accountDO.setLastUpkeepTime(task.getActualEndTime());
        //下次保养日期
        accountDO.setNextUpkeepTime(task.getActualEndTime().plusDays(upkeepCategoryDO.getUpkeepPeriod()));
        accountMapper.updateById(accountDO);
        //统计
        UpkeepStaticsDO staticsDO = new UpkeepStaticsDO();
        staticsDO.setAccountId(accountDO.getId());
        staticsDO.setDrawingNoId(task.getDrawingNoId());
        staticsDO.setUpkeepId(task.getUpkeepId());
        //获取原统计记录
        if (upkeepStaticsMapper.selectCount(new LambdaQueryWrapper<UpkeepStaticsDO>().eq(UpkeepStaticsDO::getAccountId, accountDO.getId())) > 0) {
            staticsDO = upkeepStaticsMapper.selectOne(new LambdaQueryWrapper<UpkeepStaticsDO>().eq(UpkeepStaticsDO::getAccountId, accountDO.getId()));
            staticsDO.setUpkeepCounts(staticsDO.getUpkeepCounts() + 1);
            staticsDO.setUpkeepTotalTime(staticsDO.getUpkeepTotalTime()+ task.getActualExecutionDuration() );
        }else{
            staticsDO.setUpkeepCounts(1L);
            staticsDO.setUpkeepTotalTime(task.getActualExecutionDuration());
        }

        upkeepStaticsMapper.insertOrUpdate(staticsDO);
        deleteUpkeepTobe(tobe.getId());
        return true;
    }

}